﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using AjaxStack.Support;

namespace AjaxStack.Handlers
{
	public class JavascriptHandler : IHttpHandler
	{
		public static string AppendAfterJavascriptNamespace = ConfigUtils.GetAppSetting("AppendAfterJavascriptNamespace", "");

		public void ProcessRequest(HttpContext context)
		{
			context.Response.ContentType = "text/javascript";

			HtmlHandler.WriteAllPages();

			var jsApiInNamespace = WrapJavascriptInNamespace(GetJavascriptAppText());
			context.Response.Write(jsApiInNamespace);
			context.Response.End();
		}

		public static string GetJavascriptAppText()
		{
			var jsAbsolutePath = "~/js/".MapHostAbsolutePath();
			var jsText = GetAllJavascript(jsAbsolutePath);
			return jsText;
		}

		public static string GetJavascriptAppTextExcluding(List<string> excludeLinesContainingFilter)
		{
			if (excludeLinesContainingFilter == null || excludeLinesContainingFilter.Count == 0)
				return GetJavascriptAppText();

			var jsAbsolutePath = "~/js/".MapHostAbsolutePath();
			return GetAllJavascript(jsAbsolutePath, "*.js", excludeLinesContainingFilter);
		}

		public static string WrapJavascriptInNamespace(string jsText)
		{
			var sb = new StringBuilder();

			sb.Append("(function(){");
			sb.Append(jsText);
			sb.Append("})();");
			sb.Append(AppendAfterJavascriptNamespace);

			return sb.ToString();
		}

		public static string GetAllJavascript(string jsAbsolutePath)
		{
			return GetAllJavascript(jsAbsolutePath, "*.js");
		}

		public static string GetAllJavascript(string jsAbsolutePath, string fileNameFilter)
		{
			var sb = new StringBuilder();
			foreach (var jsFilePath in Directory.GetFiles(jsAbsolutePath, fileNameFilter,
				SearchOption.AllDirectories))
			{
				//Can be optimized
				var jsFileText = File.ReadAllText(jsFilePath);
				sb.AppendLine(jsFileText);
			}
			return sb.ToString();
		}

		public static string GetAllJavascript(string jsAbsolutePath,
			string fileNameFilter, List<string> excludeLinesContaingFilter)
		{
			var sb = new StringBuilder();
			foreach (var jsFilePath in Directory.GetFiles(jsAbsolutePath, fileNameFilter, SearchOption.AllDirectories))
			{
				if (jsFilePath.InHiddenDirectory()) continue;

				//Can be optimized
				using (var reader = File.OpenText(jsFilePath))
				{
					string line;
					while ((line = reader.ReadLine()) != null)
					{
						if (excludeLinesContaingFilter != null
							&& line.EndsWith(";")
							&& excludeLinesContaingFilter.Any(line.Contains))
						{
							continue;
						}
						sb.AppendLine(line);
					}
				}
			}
			return sb.ToString();
		}

		public bool IsReusable
		{
			get
			{
				return false;
			}
		}
	}

}